package com.aabte.lota.auth;

import com.aabte.commons.rest.api.ApiResult;
import com.aabte.commons.rest.exception.ApiException;
import com.aabte.lota.auth.common.util.ServletUtils;
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

/**
 * @author Daniel
 * @version 1.0
 * @date 2020/4/6
 */
@Component
public class ExceptionHandlerFilter implements Filter {

  @Resource private GlobalExceptionHandler globalExceptionHandler;

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    Integer status = null;
    Throwable ex = null;
    try {
      chain.doFilter(request, response);
    } catch (ServletException e) {
      ex = e.getCause();
    } catch (ApiException e) {
      ex = e;
    } catch (Exception e) {
      status = HttpStatus.INTERNAL_SERVER_ERROR.value();
      ex = e;
    } finally {
      if (null != ex) {
        if (ex instanceof ApiException) {
          status = ((ApiException) ex).getStatus();
          ((HttpServletResponse) response).setStatus(status);
          ApiResult<Object> result =
              globalExceptionHandler.handle(request, response, (ApiException) ex);
          ServletUtils.writeBody(result);
        } else if (null != status) {
          ((HttpServletResponse) response).setStatus(status);
          ApiResult<Object> result = globalExceptionHandler.handle(request, response, ex);
          ServletUtils.writeBody(result);
        }
      }
    }
  }
}
